package com.zjw.algorithm.ready1;

import com.zjw.algorithm.utils.TreeNode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;

public class _二叉树的三种遍历 {


    //def 迭代版本 先序遍历
    public static List<Integer> firstOrderTree(TreeNode node) {
        Stack<TreeNode> stack = new Stack<>();
        if (node == null) {
            return Collections.emptyList();
        }

        List<Integer> result = new ArrayList<>();

        stack.push(node);

        while (!stack.isEmpty()) {

            TreeNode pop = stack.pop();

            result.add(pop.val);

            if (pop.right != null) {
                stack.push(pop.right);
            }

            if (pop.left != null) {
                stack.push(pop.left);
            }

        }

        return result;
    }


    public List<Integer> inorderTraversal(TreeNode node) {
        Stack<TreeNode> stack = new Stack<>();
        if (node == null) {
            return Collections.emptyList();
        }

        List<Integer> result = new ArrayList<>();
        TreeNode p = node;
        while (!stack.isEmpty() || p != null) {
            while (p != null) {
                stack.push(p);
                p = p.left;
            }
            p = stack.pop();
            result.add(p.val);
            p = p.right;
        }

        return result;
    }


    public List<Integer> postorderTraversal(TreeNode node) {
        Stack<TreeNode> stack = new Stack<>();
        if (node == null) {
            return Collections.emptyList();
        }

        List<Integer> result = new ArrayList<>();
        TreeNode p = node;
        TreeNode prev = null;
        while (!stack.isEmpty() || p != null) {
            while (p != null) {
                stack.push(p);
                p = p.left;
            }
            p = stack.pop();
            if (p.right == null || p.right == prev) {
                result.add(p.val);
                prev = p;
                p = null;
            } else {
                stack.push(p);
                p = p.right;
            }
        }

        return result;
    }


    public List<Integer> postorderTraversal2(TreeNode node) {

        Stack<TreeNode> stack = new Stack<>();
        TreeNode p = node;
        List<Integer> ans = new ArrayList<>();
        TreeNode prev = null;
        while (!stack.isEmpty() || p != null) {
            while (p != null) {
                stack.push(p);
                p = p.left;
            }

            p = stack.pop();

            if (p.right == null || prev == p.right) {
                ans.add(p.val);
                prev = p;
                p = null;
            } else {
                stack.push(p);
                p = p.right;
            }
        }

        return ans;
    }
}
